﻿using System;
using System.Collections.Generic;
using imeem.library;
using imeem.api;

namespace imeem.services
{
    public class MediaService : imeemService
    {
        #region Search

        public List<MusicData> SearchMusic(string query)
        {
            List<ContentData> mediaList = Search(query, MediaType.music, null, null);
            List<MusicData> musicList = new List<MusicData>();

            foreach (ContentData item in mediaList)
            {
                MusicData musicItem = item as MusicData;
                if (musicItem != null)
                {
                    musicList.Add(musicItem);
                }
            }

            return musicList;
        }

        public List<VideoData> SearchVideo(string query)
        {
            List<ContentData> mediaList = Search(query, MediaType.video, null, null);

            List<VideoData> videoList = new List<VideoData>();
            foreach (Item item in mediaList)
            {
                VideoData videoItem = item as VideoData;
                if (videoItem != null)
                {
                    videoList.Add(videoItem);
                }
            }

            return videoList;
        }

        public List<PhotoData> SearchPhoto(string query)
        {
            List<ContentData> mediaList = Search(query, MediaType.photo, null, null);

            List<PhotoData> photoList = new List<PhotoData>();
            foreach (Item item in mediaList)
            {
                PhotoData photoItem = item as PhotoData;
                if (photoItem != null)
                {
                    photoList.Add(photoItem);
                }
            }

            return photoList;
        }

        public List<ContentData> Search(string query, MediaType mediaType)
        {
            return Search(query, mediaType, null, null);
        }

        public List<ContentData> Search(string query, MediaType mediaType, int? offset, int? numResults)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("query", query);
            parameters.Add("mediaType", Enum.GetName(typeof(MediaType), mediaType));
            if (offset.HasValue)
            {
                parameters.Add("offset", offset.Value.ToString());
            }
            if (numResults.HasValue)
            {
                parameters.Add("numResults", numResults.Value.ToString());
            }
            imeemResult result = base.MakeRequest(imeem.dal.methods.Media.MediaSearch, parameters);

            List<ContentData> mediaList = new List<ContentData>();
            foreach (Item item in result.Items)
            {
                ContentData mediaItem = item as ContentData;
                if (mediaItem != null)
                {
                    mediaList.Add(mediaItem);
                }
            }

            return mediaList;
        }

        #endregion

        #region GetById

        public List<ContentData> GetById(params string[] mediaIds)
        {
            if (mediaIds == null || mediaIds.Length == 0)
            {
                throw new Exception("At least 1 media Id is required");
            }

            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("mediaIds", Join<string>(mediaIds));

            imeemResult result = base.MakeRequest(imeem.dal.methods.Media.MediaGetInfo, parameters);

            List<ContentData> mediaList = new List<ContentData>();
            foreach (Item item in result.Items)
            {
                ContentData mediaItem = item as ContentData;
                if (mediaItem != null)
                {
                    mediaList.Add(mediaItem);
                }
            }
            return mediaList;
        }

        #endregion

        #region GetByUser

        public List<ContentData> GetByUser(string userId, MediaType mediaTypes)
        {
            return GetByUser(userId, mediaTypes, null);
        }

        public List<ContentData> GetByUser(string userId, MediaType mediaTypes, MediaFilter? userMediaFilter)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("userId", userId);
            parameters.Add("mediaTypes", joinMediaTypes(mediaTypes));

            if (userMediaFilter.HasValue)
            {
                parameters.Add("userMediaFilter", Enum.GetName(typeof(MediaFilter), userMediaFilter));
            }

            imeemResult result = base.MakeRequest(imeem.dal.methods.Media.MediaGetByUser, parameters);

            List<ContentData> mediaList = new List<ContentData>();
            foreach (Item item in result.Items)
            {
                ContentData mediaItem = item as ContentData;
                if (mediaItem != null)
                {
                    mediaList.Add(mediaItem);
                }
            }
            return mediaList;
        }

        #endregion

        #region GetByPlaylist

        public List<ContentData> GetByPlaylist(PlaylistData playlist)
        {
            return GetByPlaylist(playlist.Id);
        }

        public List<ContentData> GetByPlaylist(string playlistId)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("playlistId", playlistId);

            imeemResult result = base.MakeRequest(imeem.dal.methods.Media.MediaGetByPlaylist, parameters);

            List<ContentData> contentList = new List<ContentData>();
            foreach (Item item in result.Items)
            {
                ContentData mediaItem = item as ContentData;
                if (mediaItem != null)
                {
                    contentList.Add(mediaItem);
                }
            }
            return contentList;
        }

        #endregion

        #region GetTopContent

        public List<ContentData> GetTopContent(MediaType mediaType)
        {
            return GetTopContent(mediaType, null, null);
        }

        public List<ContentData> GetTopContent(MediaType mediaType, string genreFilter)
        {
            return GetTopContent(mediaType, genreFilter, null);
        }

        public List<ContentData> GetTopContent(MediaType mediaType, SortFilter sortFilter)
        {
            return GetTopContent(mediaType, null, sortFilter);
        }

        public List<ContentData> GetTopContent(MediaType mediaType, string genreFilter, SortFilter? sortFilter)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("mediaType", Enum.GetName(typeof(MediaType), mediaType));
            
            if (genreFilter != null)
            {
                parameters.Add("genreFilter", genreFilter);
            }
            if (sortFilter.HasValue)
            {
                parameters.Add("sortFilter", Enum.GetName(typeof(SortFilter), sortFilter));
            }

            imeemResult result = base.MakeRequest(imeem.dal.methods.Media.MediaGetTopContent, parameters);

            List<ContentData> contentList = new List<ContentData>();
            foreach (Item item in result.Items)
            {
                ContentData mediaItem = item as ContentData;
                if (mediaItem != null)
                {
                    contentList.Add(mediaItem);
                }
            }
            return contentList;
        }

        #endregion

        #region GetRelatedContent

        public List<ContentData> GetRelatedContent(ContentData content)
        {
            return GetRelatedContent(content.Id);
        }

        public List<ContentData> GetRelatedContent(string mediaId)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("mediaId", mediaId);

            imeemResult result = base.MakeRequest(imeem.dal.methods.Media.MediaGetRelatedContent, parameters);

            List<ContentData> contentList = new List<ContentData>();
            foreach (Item item in result.Items)
            {
                ContentData mediaItem = item as ContentData;
                if (mediaItem != null)
                {
                    contentList.Add(mediaItem);
                }
            }
            return contentList;
        }

        #endregion

        #region Edit

        public bool Edit(string mediaId)
        {
            throw new NotImplementedException("Edit is not yet implemented");
        }

        #endregion

        #region Remove

        public bool Remove(string mediaId)
        {
            throw new NotImplementedException("Remove is not yet implemented");
        }

        #endregion

        #region AddFavorite

        public bool AddFavorite(string mediaId)
        {
            throw new NotImplementedException("AddFavorite is not yet implemented");
        }

        #endregion

        #region RemoveFavorite

        public bool RemoveFavorite(string mediaId)
        {
            throw new NotImplementedException("RemoveFavorite is not yet implemented");
        }

        #endregion

        #region private - joinMediaTypes

        private string joinMediaTypes(MediaType mediaTypes)
        {
            List<string> mediaTypeList = new List<string>();

            if ((mediaTypes & MediaType.music) == MediaType.music)
            {
                mediaTypeList.Add("music");
            }

            if ((mediaTypes & MediaType.video) == MediaType.video)
            {
                mediaTypeList.Add("video");
            }

            if ((mediaTypes & MediaType.photo) == MediaType.photo)
            {
                mediaTypeList.Add("photo");
            }

            return Join<string>(mediaTypeList);
        }

        #endregion
    }
}
